﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Reflection;
using MediaPortal.Configuration;
using MediaPortal.Services;
using NLog;
using NLog.Config;
using NLog.Targets;
using dlCentral.GUI;
using dlCentral.Localizations;
using dlCentral.PluginHandlers;
using dlCentral.TorrentHandlers;
using dlCentral.Settings;
using dlCentral.Utils;

namespace dlCentral {
    public class dlCentralCore {

        private static Logger logger = LogManager.GetCurrentClassLogger();

        // Returns instance to this class as we only want to have one 
        // in existance at a time.
        public static dlCentralCore Instance {
            get {
                if (_instance == null)
                    _instance = new dlCentralCore();

                return _instance;
            }
        }
        private static dlCentralCore _instance = null;

        internal PluginHandlerManager PluginHandlers {
            get { return _pluginHandlers; }
        }
        private PluginHandlerManager _pluginHandlers;


        internal TorrentHandlerManager TorrentHandlers
        {
            get { return _torrentHandlers; }
        }
        private TorrentHandlerManager _torrentHandlers;
        
        // Returns latests settings from the MediaPortal.xml file. We reload
        // on access to ensure any changes made while the program runs are honored.
        public MediaPortal.Profile.Settings MediaPortalSettings {
            get {
                MediaPortal.Profile.Settings mpSettings = new MediaPortal.Profile.Settings(Config.GetFile(Config.Dir.Config, "MediaPortal.xml"));
                return mpSettings;
            }
        }

        // Constructor. Private because we are a singleton.
        private dlCentralCore() { }

        // Should be the first thing that is run whenever the plugin launches, either
        // from the GUI or the Config Screen.
        public void Initialize() {
            InitLogger();
            LogStartupBanner();
            InitLocalization();
            InitSettings();
            InitPluginHandlers();
            InitTorrentHandlers();
        }

        // Initializes the logging system.
        private void InitLogger() {
            string fullLogFilePath = Config.GetFile(Config.Dir.Log, dlCentralUtils.LogFileName);
            string fullOldLogFilePath = Config.GetFile(Config.Dir.Log, dlCentralUtils.OldLogFileName);
            
            // backup the old log file if it exists
            try {
                if (File.Exists(fullLogFilePath)) File.Copy(fullLogFilePath, fullOldLogFilePath, true);
                File.Delete(fullLogFilePath);
            }
            catch (Exception e)
            {
                logger.ErrorException("Error setting up logging paths\n", e);
            }

            LoggingConfiguration config = LogManager.Configuration ?? new LoggingConfiguration();

            // build logging rules for our logger
            FileTarget fileTarget = new FileTarget();
            fileTarget.FileName = Config.GetFile(Config.Dir.Log, dlCentralUtils.LogFileName);
            fileTarget.Layout = "${date:format=dd-MMM-yyyy HH\\:mm\\:ss.fff} " +
                                "${level:fixedLength=true:padding=5} " +
                                "[${logger:fixedLength=true:padding=20:shortName=true}]: ${message} " +
                                "${exception:format=tostring}";
            config.AddTarget("file", fileTarget);

            LogLevel logLevel = GetMediaportalLogLevel();

            // if the plugin was compiled in DEBUG mode, always default to debug logging
            #if DEBUG
            logLevel = LogLevel.Debug;
            #endif

            // add the previously defined rules and targets to the logging configuration
            LoggingRule rule = new LoggingRule("dlCentral*", logLevel, fileTarget);
            config.LoggingRules.Add(rule);
            
            LogManager.Configuration = config;
        }

        private LogLevel GetMediaportalLogLevel()
        {
            LogLevel logLevel;
            MediaPortal.Profile.Settings xmlreader = MediaPortalSettings;
            switch ((Level)xmlreader.GetValueAsInt("general", "loglevel", 0)) {
                case Level.Error:
                    logLevel = LogLevel.Error;
                    break;
                case Level.Warning:
                    logLevel = LogLevel.Warn;
                    break;
                case Level.Information:
                    logLevel = LogLevel.Info;
                    break;
                case Level.Debug:
                default:
                    logLevel = LogLevel.Debug;
                    break;
            }
            return logLevel;
        }

        // Logs a startup message to the log files.
        private void LogStartupBanner() {
            Version ver = Assembly.GetExecutingAssembly().GetName().Version;
            logger.Info(string.Format("dlCentral ({0}.{1}.{2}.{3})", ver.Major, ver.Minor, ver.Build, ver.Revision));
            logger.Info("Plugin launched");
        }

        private void InitLocalization() {
            logger.Info("Initializing localization");
            Localization.Init();
            Localization.TranslateSkin();
        }

        private void InitSettings() {
            logger.Info("Loading settings from dlCentral.xml...");
            try {
                SettingsManager.Load(Config.GetFile(Config.Dir.Config, dlCentralUtils.SettingsFileName));
                logger.Info("Loading settings from dlCentral.xml successful.");
            }
            catch (Exception e) {
                logger.ErrorException("Loading settings from dlCentral.xml unsuccessful\n", e);
            }
        }

        private void InitPluginHandlers() {
            logger.Info("Initializing plugin handlers");
            _pluginHandlers = new PluginHandlerManager();
        }

        private void InitTorrentHandlers()
        {
            logger.Info("Initializing torrent handlers");
            _torrentHandlers = new TorrentHandlerManager();
        }

    }
}
